﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Windows;
using System.Threading;
using System.Globalization;

namespace DrawingCurveDT2.Controls
{
    //AH 110424, created
    public class CurveDrawer
    {
        #region Properties
        public DrawingGroup DrawingGroup { get { return drawingGroup; } }
        private List<Point> _Points;
        public List<Point> Points
        {
            get { return _Points; }
            set { _Points = value; applySegments(value); }
        }

        private Size _Size;
        public Size Size { get { return _Size; } set { _Size = value; applySize(value); } }
        private Pen _Pen { get { return _Pen; } set { _Pen = value; applyPen(value); } }
        public Pen Pen { get; set; }
        public Brush Background { get; set; }//Thinkess is always 1 here


        private double _ScaleX;
        public double ScaleX { get { return _ScaleX; } set { _ScaleX = value; applySize(this.Size); } }
        private double _ScaleY;
        public double ScaleY
        {
            get { return _ScaleY; }
            set
            {
                _ScaleY = value; //applySize(this.Size); 
            }
        }

        #region Applying Properties
        private void applySegments(List<Point> points)
        {
            List<Point> scaledPoints = new List<Point>();
            foreach (Point p in points)
                scaledPoints.Add(scalePoint(p));

            PathFigure myPathFigure = new PathFigure();
            if (scaledPoints.Count > 0)
                myPathFigure.StartPoint = scaledPoints[0];

            //curPathSegmentCollection.Clear();
            foreach (Point p in scaledPoints)
            {
                curPathSegmentCollection.Add(new LineSegment(p, true));
            }

            myPathFigure.Segments = curPathSegmentCollection;
            PathFigureCollection myPathFigureCollection = new PathFigureCollection();
            myPathFigureCollection.Add(myPathFigure);
            PathGeometry myPathGeometry = new PathGeometry();
            curGeo.Figures = myPathFigureCollection;

            bgGD.Geometry = bgGeo; bgGD.Brush = Background;//to be transparent
            curGD.Geometry = curGeo; curGD.Pen = this.Pen;
        }

        private Point scalePoint(Point p)
        {
            if (ScaleX == 1 && ScaleY == 1) return p;//no need to scale
            Point result = new Point(p.X * ScaleX, p.Y * ScaleY);
            return result;
        }

        private void applySize(System.Windows.Size size)
        {
            curScaleTrans.CenterY = size.Height / 2;
            bgGeo.Rect = new Rect(0, 0, size.Width * ScaleX, size.Height * ScaleY);
        }

        private void applyPen(System.Windows.Media.Pen pen)
        {
            curGD.Pen = pen;
        }
        #endregion
        #endregion

        #region Internal fields
        DrawingGroup drawingGroup = new DrawingGroup();
        GeometryDrawing bgGD = new GeometryDrawing();
        GeometryDrawing curGD = new GeometryDrawing();

        RectangleGeometry bgGeo = new RectangleGeometry();

        PathGeometry curGeo = new PathGeometry();
        PathSegmentCollection curPathSegmentCollection = new PathSegmentCollection();
        ScaleTransform curScaleTrans = new ScaleTransform() { ScaleY = -1 };//Adjust points so they fit in a normal Y-Axis
        #endregion

        #region Internal methods
        public CurveDrawer()
        {
            setDefaultValues();

            curGeo.Transform = curScaleTrans;

            drawingGroup.Children.Add(bgGD);
            drawingGroup.Children.Add(curGD);
        }

        private void setDefaultValues()
        {
            Pen = new System.Windows.Media.Pen(Brushes.Black, 1);//default color and size
            Background = Brushes.Transparent;//default background
            Size = new Size(100, 100);
            ScaleX = 1;
            ScaleY = 1;
        }
        #endregion

        //make it as a list of Point that know about each others, so they dont overlap
        public void PlacePoint(int index, string Label)
        {
            #region The ring of the point
            EllipseGeometry el1 = new EllipseGeometry();
            el1.Transform = curScaleTrans;
            if (index > Points.Count) return;
            Point scaledP = scalePoint(Points[index]);

            el1.Center = scaledP;
            el1.RadiusX = 2;
            el1.RadiusY = 2;

            GeometryDrawing g1 = new GeometryDrawing();
            g1.Geometry = el1;
            g1.Pen = new Pen(Brushes.Black, 1);
            drawingGroup.Children.Add(g1);
            #endregion

            double fontSize = 7;
            FormattedText ft = new FormattedText(Label, CultureInfo.GetCultureInfo("en-us"),
                System.Windows.FlowDirection.LeftToRight, new Typeface("Arial"), fontSize, Brushes.Black);

            Geometry textGeometry = ft.BuildGeometry(new Point(scaledP.X ,Size.Height- scaledP.Y - 12));
            
            GeometryDrawing g2 = new GeometryDrawing();
            
            g2.Geometry = textGeometry;
            g2.Brush = Brushes.Black;
            //g2.Pen = new Pen(Brushes.Black, 1);
            drawingGroup.Children.Add(g2);
        }
    }
}
